Micron Document
🎖️GitЯра🎖️

Node / meshtastic / Meshtastic-Android / files / core / database / src / commonTest / kotlin / org / meshtastic / core / database / DatabaseManagerWriterAdmissionTest.kt

Displaying Raw • Download

core/database/src/commonTest/kotlin/org/meshtastic/core/database/DatabaseManagerWriterAdmissionTest.kt d5848ad5e02bd9b5b1726bedfa51ceb0faaa0240 (d5848ad5) Text, 11.22 KB

T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.core.database

Tff7b72import T7ee787kotlinx.coroutines.CompletableDeferred
Tff7b72import T7ee787kotlinx.coroutines.async
Tff7b72import T7ee787kotlinx.coroutines.cancelAndJoin
Tff7b72import T7ee787kotlinx.coroutines.launch
Tff7b72import T7ee787kotlinx.coroutines.test.advanceTimeBy
Tff7b72import T7ee787kotlinx.coroutines.test.runTest
Tff7b72import T7ee787kotlin.test.AfterTest
Tff7b72import T7ee787kotlin.test.BeforeTest
Tff7b72import T7ee787kotlin.test.Test
Tff7b72import T7ee787kotlin.test.assertEquals
Tff7b72import T7ee787kotlin.test.assertFalse
Tff7b72import T7ee787kotlin.test.assertNotNull
Tff7b72import T7ee787kotlin.test.assertTrue

Tff7b72class T56d364DatabaseManagerWriterAdmissionTest Tb4b4b4: Te6edf3DatabaseManagerTestFixtureTb4b4b4(Tb4b4b4) Tb4b4b4{

Tf0883e@BeforeTest Tff7b72fun Td2a8ffsetUpTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3setUpFixtureTb4b4b4(Tb4b4b4)

Tf0883e@AfterTest Tff7b72fun Td2a8fftearDownTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3tearDownFixtureTb4b4b4(Tb4b4b4)

Tf0883e@Test
Tff7b72fun Td2a8ffwriterArrivingDuringDrainIsBlockedAndReleasedToDestOnCommitTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTestTb4b4b4(Te6edf3testDispatcherTb4b4b4) Tb4b4b4{
Tff7b72val Tb4b4b4(Te6edf3dbATb4b4b4, Te6edf3_Tb4b4b4) Tff7b72= Te6edf3setupTwoDatabasesTb4b4b4(Tb4b4b4)
Te6edf3managerTb4b4b4.Te6edf3performRealMerge Tff7b72= Tff7b72false

T8b949e// Hold a pre-existing source writer so the drain stays pending and a new writer can arrive into the gate.
Tff7b72val Te6edf3preGate Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3preWriter Tff7b72= Te6edf3launch Tb4b4b4{
Te6edf3managerTb4b4b4.Te6edf3withDb Tb4b4b4{
Te6edf3preGateTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Tff7b72null
Tb4b4b4}
Tb4b4b4}
Tff7b72val Te6edf3associateJob Tff7b72= Te6edf3launch Tb4b4b4{ Te6edf3managerTb4b4b4.Te6edf3associateCurrentDeviceTb4b4b4(Te6edf3nodeNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3deviceId Tff7b72= Ta5d6ff"Ta5d6ffdeadbeefdeadbeefTa5d6ff"Tb4b4b4) Tb4b4b4}

Tff7b72val Te6edf3newWriterStarted Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3newWriterDb Tff7b72= Te6edf3CompletableDeferredTff7b72<Te6edf3MeshtasticDatabaseTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72var Te6edf3newWriterInvocationCount Tff7b72= T79c0ff0
Tff7b72val Te6edf3newWriterJob Tff7b72= Te6edf3launch Tb4b4b4{
Te6edf3managerTb4b4b4.Te6edf3withDb Tb4b4b4{ Te6edf3db Tff7b72-Tff7b72>
Te6edf3newWriterInvocationCount Tff7b72+Tff7b72= T79c0ff1
Te6edf3newWriterStartedTb4b4b4.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Te6edf3newWriterDbTb4b4b4.Te6edf3completeTb4b4b4(Te6edf3dbTb4b4b4)
Tff7b72null
Tb4b4b4}
Tb4b4b4}

T8b949e// The new writer must be suspended at the admission gate, not running its block.
Te6edf3assertFalseTb4b4b4(Te6edf3newWriterStartedTb4b4b4.Te6edf3isCompletedTb4b4b4, Ta5d6ff"Ta5d6ffnew writer must block at the admission gate during the drainTa5d6ff"Tb4b4b4)
Te6edf3assertFalseTb4b4b4(Te6edf3newWriterDbTb4b4b4.Te6edf3isCompletedTb4b4b4, Ta5d6ff"Ta5d6ffnew writer must not have captured a DB yetTa5d6ff"Tb4b4b4)

T8b949e// Release the pre-existing writer: drain completes, merge commits, gate releases onto dest.
Te6edf3preGateTb4b4b4.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Te6edf3newWriterJobTb4b4b4.Te6edf3joinTb4b4b4(Tb4b4b4)
Te6edf3associateJobTb4b4b4.Te6edf3joinTb4b4b4(Tb4b4b4)
Te6edf3preWriterTb4b4b4.Te6edf3joinTb4b4b4(Tb4b4b4)

Te6edf3assertTrueTb4b4b4(Te6edf3newWriterStartedTb4b4b4.Te6edf3isCompletedTb4b4b4, Ta5d6ff"Ta5d6ffnew writer must be released after the merge commitsTa5d6ff"Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3associateJobTb4b4b4.Te6edf3isCompletedTb4b4b4, Ta5d6ff"Ta5d6ffassociation must completeTa5d6ff"Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3newWriterInvocationCountTb4b4b4, Ta5d6ff"Ta5d6ffblocked writer must run exactly onceTa5d6ff"Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3dbATb4b4b4, Te6edf3newWriterDbTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffnew writer released onto destination after successful mergeTa5d6ff"Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3dbATb4b4b4, Te6edf3managerTb4b4b4.Te6edf3currentDbTb4b4b4.Te6edf3valueTb4b4b4, Ta5d6ff"Ta5d6ffdestination is canonical after commitTa5d6ff"Tb4b4b4)
Te6edf3assertFalseTb4b4b4(Te6edf3managerTb4b4b4.Te6edf3debugWriterGateArmedTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72val Tb4b4b4(Te6edf3writersTb4b4b4, Te6edf3waitersTb4b4b4) Tff7b72= Te6edf3managerTb4b4b4.Te6edf3debugWriterCountsTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3writersTb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3waitersTb4b4b4)
Tb4b4b4}

T8b949e/** A successful merge releases the blocked writer onto destination (not source). */
Tf0883e@Test
Tff7b72fun Td2a8ffsuccessfulMergeReleasesBlockedWriterOntoDestinationTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTestTb4b4b4(Te6edf3testDispatcherTb4b4b4) Tb4b4b4{
Tff7b72val Tb4b4b4(Te6edf3dbATb4b4b4, Te6edf3_Tb4b4b4) Tff7b72= Te6edf3setupTwoDatabasesTb4b4b4(Tb4b4b4)
Te6edf3managerTb4b4b4.Te6edf3performRealMerge Tff7b72= Tff7b72false

Tff7b72val Te6edf3preGate Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3preWriter Tff7b72= Te6edf3launch Tb4b4b4{
Te6edf3managerTb4b4b4.Te6edf3withDb Tb4b4b4{
Te6edf3preGateTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Tff7b72null
Tb4b4b4}
Tb4b4b4}
Tff7b72val Te6edf3associateJob Tff7b72= Te6edf3launch Tb4b4b4{ Te6edf3managerTb4b4b4.Te6edf3associateCurrentDeviceTb4b4b4(Te6edf3nodeNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3deviceId Tff7b72= Ta5d6ff"Ta5d6ffdeadbeefdeadbeefTa5d6ff"Tb4b4b4) Tb4b4b4}

Tff7b72val Te6edf3newWriterDb Tff7b72= Te6edf3CompletableDeferredTff7b72<Te6edf3MeshtasticDatabaseTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72var Te6edf3newWriterInvocationCount Tff7b72= T79c0ff0
Tff7b72val Te6edf3newWriterJob Tff7b72= Te6edf3launch Tb4b4b4{
Te6edf3managerTb4b4b4.Te6edf3withDb Tb4b4b4{ Te6edf3db Tff7b72-Tff7b72>
Te6edf3newWriterInvocationCount Tff7b72+Tff7b72= T79c0ff1
Te6edf3newWriterDbTb4b4b4.Te6edf3completeTb4b4b4(Te6edf3dbTb4b4b4)
Tff7b72null
Tb4b4b4}
Tb4b4b4}

Te6edf3assertFalseTb4b4b4(Te6edf3newWriterDbTb4b4b4.Te6edf3isCompletedTb4b4b4, Ta5d6ff"Ta5d6ffnew writer must block during the drainTa5d6ff"Tb4b4b4)
Te6edf3preGateTb4b4b4.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Tff7b72val Te6edf3usedDb Tff7b72= Te6edf3newWriterDbTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3dbATb4b4b4, Te6edf3usedDbTb4b4b4, Ta5d6ff"Ta5d6ffblocked writer released onto destination after successful mergeTa5d6ff"Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3dbATb4b4b4, Te6edf3managerTb4b4b4.Te6edf3currentDbTb4b4b4.Te6edf3valueTb4b4b4, Ta5d6ff"Ta5d6ffdestination is canonical after commitTa5d6ff"Tb4b4b4)

Te6edf3associateJobTb4b4b4.Te6edf3joinTb4b4b4(Tb4b4b4)
Te6edf3preWriterTb4b4b4.Te6edf3joinTb4b4b4(Tb4b4b4)
Te6edf3newWriterJobTb4b4b4.Te6edf3joinTb4b4b4(Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3associateJobTb4b4b4.Te6edf3isCompletedTb4b4b4, Ta5d6ff"Ta5d6ffassociation must completeTa5d6ff"Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3newWriterInvocationCountTb4b4b4, Ta5d6ff"Ta5d6ffblocked writer must run exactly onceTa5d6ff"Tb4b4b4)
Te6edf3assertFalseTb4b4b4(Te6edf3managerTb4b4b4.Te6edf3debugWriterGateArmedTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72val Tb4b4b4(Te6edf3writersTb4b4b4, Te6edf3waitersTb4b4b4) Tff7b72= Te6edf3managerTb4b4b4.Te6edf3debugWriterCountsTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3writersTb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3waitersTb4b4b4)
Tb4b4b4}

T8b949e/** A pre-commit merge failure releases the blocked writer onto source; the destination is never activated. */
Tf0883e@Test
Tff7b72fun Td2a8ffpreCommitMergeFailureReleasesBlockedWriterOntoSourceTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTestTb4b4b4(Te6edf3testDispatcherTb4b4b4) Tb4b4b4{
Tff7b72val Tb4b4b4(Te6edf3dbATb4b4b4, Te6edf3dbBTb4b4b4) Tff7b72= Te6edf3setupTwoDatabasesTb4b4b4(Tb4b4b4)

Te6edf3managerTb4b4b4.Te6edf3failMergeWith Tff7b72= Te6edf3RuntimeExceptionTb4b4b4(Ta5d6ff"Ta5d6ffsimulated pre-commit merge failureTa5d6ff"Tb4b4b4)

Tff7b72val Te6edf3preGate Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3preWriter Tff7b72= Te6edf3launch Tb4b4b4{
Te6edf3managerTb4b4b4.Te6edf3withDb Tb4b4b4{
Te6edf3preGateTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Tff7b72null
Tb4b4b4}
Tb4b4b4}
Tff7b72val Te6edf3associateJob Tff7b72= Te6edf3launch Tb4b4b4{ Te6edf3managerTb4b4b4.Te6edf3associateCurrentDeviceTb4b4b4(Te6edf3nodeNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3deviceId Tff7b72= Ta5d6ff"Ta5d6ffdeadbeefdeadbeefTa5d6ff"Tb4b4b4) Tb4b4b4}

Tff7b72val Te6edf3newWriterDb Tff7b72= Te6edf3CompletableDeferredTff7b72<Te6edf3MeshtasticDatabaseTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3newWriterJob Tff7b72= Te6edf3launch Tb4b4b4{
Te6edf3managerTb4b4b4.Te6edf3withDb Tb4b4b4{ Te6edf3db Tff7b72-Tff7b72>
Te6edf3newWriterDbTb4b4b4.Te6edf3completeTb4b4b4(Te6edf3dbTb4b4b4)
Tff7b72null
Tb4b4b4}
Tb4b4b4}

Te6edf3preGateTb4b4b4.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Tff7b72val Te6edf3usedDb Tff7b72= Te6edf3newWriterDbTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3dbBTb4b4b4, Te6edf3usedDbTb4b4b4, Ta5d6ff"Ta5d6ffblocked writer released onto source after pre-commit merge failureTa5d6ff"Tb4b4b4)
Te6edf3associateJobTb4b4b4.Te6edf3joinTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3dbBTb4b4b4, Te6edf3managerTb4b4b4.Te6edf3currentDbTb4b4b4.Te6edf3valueTb4b4b4, Ta5d6ff"Ta5d6ffsource remains active after merge failureTa5d6ff"Tb4b4b4)

Te6edf3preWriterTb4b4b4.Te6edf3joinTb4b4b4(Tb4b4b4)
Te6edf3newWriterJobTb4b4b4.Te6edf3joinTb4b4b4(Tb4b4b4)
Tb4b4b4}

T8b949e/**
* Cancelling the attempt while a writer is blocked at the gate releases the gate onto source and leaves no waiter
* leaked.
*/
Tf0883e@Test
Tff7b72fun Td2a8ffcancellationReleasesAdmissionGateOntoSourceTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTestTb4b4b4(Te6edf3testDispatcherTb4b4b4) Tb4b4b4{
Tff7b72val Tb4b4b4(Te6edf3dbATb4b4b4, Te6edf3dbBTb4b4b4) Tff7b72= Te6edf3setupTwoDatabasesTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3preGate Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3preWriter Tff7b72= Te6edf3launch Tb4b4b4{
Te6edf3managerTb4b4b4.Te6edf3withDb Tb4b4b4{
Te6edf3preGateTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Tff7b72null
Tb4b4b4}
Tb4b4b4}
Tff7b72val Te6edf3associateJob Tff7b72= Te6edf3launch Tb4b4b4{ Te6edf3managerTb4b4b4.Te6edf3associateCurrentDeviceTb4b4b4(Te6edf3nodeNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3deviceId Tff7b72= Ta5d6ff"Ta5d6ffdeadbeefdeadbeefTa5d6ff"Tb4b4b4) Tb4b4b4}

Tff7b72val Te6edf3newWriterDb Tff7b72= Te6edf3CompletableDeferredTff7b72<Te6edf3MeshtasticDatabaseTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3newWriterJob Tff7b72= Te6edf3launch Tb4b4b4{
Te6edf3managerTb4b4b4.Te6edf3withDb Tb4b4b4{ Te6edf3db Tff7b72-Tff7b72>
Te6edf3newWriterDbTb4b4b4.Te6edf3completeTb4b4b4(Te6edf3dbTb4b4b4)
Tff7b72null
Tb4b4b4}
Tb4b4b4}

Te6edf3associateJobTb4b4b4.Te6edf3cancelAndJoinTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3usedDb Tff7b72= Te6edf3newWriterDbTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3dbBTb4b4b4, Te6edf3usedDbTb4b4b4, Ta5d6ff"Ta5d6ffgate released onto source when the attempt is cancelledTa5d6ff"Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3dbBTb4b4b4, Te6edf3managerTb4b4b4.Te6edf3currentDbTb4b4b4.Te6edf3valueTb4b4b4, Ta5d6ff"Ta5d6ffsource active after cancellationTa5d6ff"Tb4b4b4)

Te6edf3preGateTb4b4b4.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Te6edf3preWriterTb4b4b4.Te6edf3joinTb4b4b4(Tb4b4b4)
Te6edf3newWriterJobTb4b4b4.Te6edf3joinTb4b4b4(Tb4b4b4)
Tb4b4b4}

T8b949e/**
* After a full association cycle with an admission-gated writer, the writer tracker holds no live writers and no
* pending drain waiters — counts and waiters are balanced.
*/
Tf0883e@Test
Tff7b72fun Td2a8ffwriterCountsAndDrainWaitersRemainBalancedTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTestTb4b4b4(Te6edf3testDispatcherTb4b4b4) Tb4b4b4{
Tff7b72val Tb4b4b4(Te6edf3destinationTb4b4b4, Te6edf3_Tb4b4b4) Tff7b72= Te6edf3setupTwoDatabasesTb4b4b4(Tb4b4b4)
Te6edf3managerTb4b4b4.Te6edf3performRealMerge Tff7b72= Tff7b72false

Tff7b72val Te6edf3preGate Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3preWriter Tff7b72= Te6edf3launch Tb4b4b4{
Te6edf3managerTb4b4b4.Te6edf3withDb Tb4b4b4{
Te6edf3preGateTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Tff7b72null
Tb4b4b4}
Tb4b4b4}
Tff7b72val Te6edf3associateJob Tff7b72= Te6edf3launch Tb4b4b4{ Te6edf3managerTb4b4b4.Te6edf3associateCurrentDeviceTb4b4b4(Te6edf3nodeNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3deviceId Tff7b72= Ta5d6ff"Ta5d6ffdeadbeefdeadbeefTa5d6ff"Tb4b4b4) Tb4b4b4}
Tff7b72var Te6edf3newWriterInvocationCount Tff7b72= T79c0ff0
Tff7b72val Te6edf3newWriterDb Tff7b72= Te6edf3CompletableDeferredTff7b72<Te6edf3MeshtasticDatabaseTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3newWriterJob Tff7b72= Te6edf3launch Tb4b4b4{
Te6edf3managerTb4b4b4.Te6edf3withDb Tb4b4b4{ Te6edf3db Tff7b72-Tff7b72>
Te6edf3newWriterInvocationCount Tff7b72+Tff7b72= T79c0ff1
Te6edf3newWriterDbTb4b4b4.Te6edf3completeTb4b4b4(Te6edf3dbTb4b4b4)
Tff7b72null
Tb4b4b4}
Tb4b4b4}

Te6edf3preGateTb4b4b4.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Te6edf3associateJobTb4b4b4.Te6edf3joinTb4b4b4(Tb4b4b4)
Te6edf3preWriterTb4b4b4.Te6edf3joinTb4b4b4(Tb4b4b4)
Te6edf3newWriterJobTb4b4b4.Te6edf3joinTb4b4b4(Tb4b4b4)

Te6edf3assertTrueTb4b4b4(Te6edf3associateJobTb4b4b4.Te6edf3isCompletedTb4b4b4, Ta5d6ff"Ta5d6ffassociation must completeTa5d6ff"Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3newWriterInvocationCountTb4b4b4, Ta5d6ff"Ta5d6ffblocked writer must run exactly onceTa5d6ff"Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3destinationTb4b4b4, Te6edf3newWriterDbTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffblocked writer must use destinationTa5d6ff"Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3destinationTb4b4b4, Te6edf3managerTb4b4b4.Te6edf3currentDbTb4b4b4.Te6edf3valueTb4b4b4, Ta5d6ff"Ta5d6ffdestination must be canonicalTa5d6ff"Tb4b4b4)
Te6edf3assertFalseTb4b4b4(Te6edf3managerTb4b4b4.Te6edf3debugWriterGateArmedTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72val Tb4b4b4(Te6edf3writersTb4b4b4, Te6edf3waitersTb4b4b4) Tff7b72= Te6edf3managerTb4b4b4.Te6edf3debugWriterCountsTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3writersTb4b4b4, Ta5d6ff"Ta5d6ffno leaked writers after associationTa5d6ff"Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3waitersTb4b4b4, Ta5d6ff"Ta5d6ffno pending drain waiters after associationTa5d6ff"Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ffclosedPoolFailureAfterSwitchDoesNotReplayCallbackTb4b4b4(Tb4b4b4) Tff7b72=
Te6edf3runTestTb4b4b4(Te6edf3testDispatcherTb4b4b4) Tb4b4b4{ Te6edf3assertClosedPoolFailureIsNotReplayedAfterSwitchTb4b4b4(Tb4b4b4) Tb4b4b4}

T8b949e/** A gate that never completes fails admission after a bounded wait without running or registering the writer. */
Tf0883e@Test
Tff7b72fun Td2a8ffwriterAdmissionGateTimeoutIsBoundedAndBalancedTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTestTb4b4b4(Te6edf3testDispatcherTb4b4b4) Tb4b4b4{
Te6edf3setupTwoDatabasesTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3mergeStarted Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3releaseMerge Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Te6edf3managerTb4b4b4.Te6edf3beforeMerge Tff7b72= Tb4b4b4{ Te6edf3_Tb4b4b4, Te6edf3_Tb4b4b4, Te6edf3_ Tff7b72-Tff7b72>
Te6edf3mergeStartedTb4b4b4.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Te6edf3releaseMergeTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tff7b72val Te6edf3associateJob Tff7b72= Te6edf3launch Tb4b4b4{ Te6edf3managerTb4b4b4.Te6edf3associateCurrentDeviceTb4b4b4(Te6edf3nodeNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3deviceId Tff7b72= Ta5d6ff"Ta5d6ffdeadbeefdeadbeefTa5d6ff"Tb4b4b4) Tb4b4b4}
Te6edf3mergeStartedTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Tff7b72var Te6edf3writerBlockRan Tff7b72= Tff7b72false
Tff7b72val Te6edf3waitingWriter Tff7b72= Te6edf3async Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3managerTb4b4b4.Te6edf3withDb Tb4b4b4{
Te6edf3writerBlockRan Tff7b72= Tff7b72true
Tff7b72null
Tb4b4b4}
Tff7b72null
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3failureTb4b4b4: Te6edf3IllegalStateExceptionTb4b4b4) Tb4b4b4{
Te6edf3failure
Tb4b4b4}
Tb4b4b4}

Te6edf3advanceTimeByTb4b4b4(T79c0ff3T79c0ff0Te6edf3_001Tb4b4b4)
Tff7b72val Te6edf3failure Tff7b72= Te6edf3waitingWriterTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Te6edf3assertNotNullTb4b4b4(Te6edf3failureTb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3failureTb4b4b4.Te6edf3messageTb4b4b4.Te6edf3orEmptyTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3containsTb4b4b4(Ta5d6ff"Ta5d6ffTimed out waiting 30000msTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3assertFalseTb4b4b4(Te6edf3writerBlockRanTb4b4b4, Ta5d6ff"Ta5d6ffa timed-out writer must never run its callbackTa5d6ff"Tb4b4b4)
Tff7b72val Tb4b4b4(Te6edf3writersDuringMergeTb4b4b4, Te6edf3waitersDuringMergeTb4b4b4) Tff7b72= Te6edf3managerTb4b4b4.Te6edf3debugWriterCountsTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3writersDuringMergeTb4b4b4, Ta5d6ff"Ta5d6ffgate wait must not register a writerTa5d6ff"Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3waitersDuringMergeTb4b4b4)

Te6edf3releaseMergeTb4b4b4.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Te6edf3associateJobTb4b4b4.Te6edf3joinTb4b4b4(Tb4b4b4)
Te6edf3assertFalseTb4b4b4(Te6edf3managerTb4b4b4.Te6edf3debugWriterGateArmedTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72val Tb4b4b4(Te6edf3writersTb4b4b4, Te6edf3waitersTb4b4b4) Tff7b72= Te6edf3managerTb4b4b4.Te6edf3debugWriterCountsTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3writersTb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3waitersTb4b4b4)
Tb4b4b4}
Tb4b4b4}

Served by rngit 1.5.0 - Generated in 0.08s